好的,我們今天要開始套版了!!
首先先到 GitHub 上把我已經切好的版型下載下來。
不過為了避免有人不知道怎麼下載,容我先小小地說明一下:
點擊 GitHub 的連結開啟新的視窗之後,應該會看到以下畫面:
然後點擊紅框中的 Clone or download 按鈕之後,會出現一個視窗:
接著再點擊紅框中的 Download ZIP 按鈕之後就能夠成功下載。
下載完之後是個壓縮檔,記得要解壓縮噢!!
為方便後續分辨,之後都會稱這個下載下來的資料夾為 「素材」。
拿到素材之後,裡面的資料夾結構是:
index.html
- 首頁不解釋。pages/
- 這裡面是其他頁面的 HTML 檔。assets/
- 這裡面是 CSS 與圖片檔。首先我們先將素材裡 assets/
底下的 images/
整個資料夾搬到我們專案 src/
底下的 assets/
裡。這裡面是整個網站都會用到的圖片檔。
接著再打開素材裡 assets/css/
底下的 common.css
檔,這裡面都是全站共用的樣式設定。一樣將裡面的設定全部複製貼上到我們專案 src/
底下的 styles.css
裡。
然後打開素材裡的 index.html
,我們先把共用區塊的 HTML 複製到我們專案裡的 app.component.html
裡。
這邊要留意的是, index.html
是完整的 HTML 檔,但我們其實只需要先複製其中這兩個區塊的 HTML :
複製貼上後,再把路由插座放在中間那塊各頁要自己處理的區塊,像這樣:
完成後就可以來看一下畫面:
可以看到大致上的樣式都有出來了,不過你會看到有些地方會跑版。而這部份是因為我有使用 Google Material Design 裡的 Icon 造成的。
這個問題只要我們在 index.html
的 <head></head>
加上:
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
等待畫面重整完應該就會正常了:
不過雖然畫面是正常的,但我們還需要調整一下導覽列的連結:
上圖中的連結需要用 routerLink
來處理一下:
<!-- 選單區域開始 -->
<nav class="desktop">
<ul>
<li><a [routerLink]="[path.home]">首頁</a></li>
<li><a [routerLink]="[path.products]">甜點</a></li>
<li><a [routerLink]="[path.login]">登入</a></li>
</ul>
</nav>
<nav class="mobile">
<i class="material-icons">menu</i>
<ul>
<li><a [routerLink]="[path.home]">首頁</a></li>
<li><a [routerLink]="[path.products]">甜點</a></li>
<li><a [routerLink]="[path.login]">登入</a></li>
</ul>
</nav>
<!-- 選單區域結束 -->
<!-- 購物車icon區域開始 -->
<a [routerLink]="[path.cart]" class="cart">
<i class="material-icons">shopping_cart</i>
</a>
<!-- 購物車icon區域結束 -->
處理完之後記得點看看是不是可以正常運作噢!
接下來換開啟 home.component.html
檔,一樣是素材裡的 index.html
檔,只不過這次換成另一個區塊:
直接整塊複製貼上到 home.component.html
之後,再打開素材裡 assets/css/
底下的 index.css
檔,這個檔裡的樣式設定都是給 HomeComponent 的 Temeplate 用的。
一樣全部複製貼到 home.component.css
檔裡,存檔後應該會發現編譯器會報錯:
這是因為原本設定背景圖片的時候是使用相對路徑來連結圖片,不過在 Angular 裡要使用絕對路徑,所以我們只要把 ../
都替換成 /assets/
就可以了。
改完之後應該會看到圖片都會正常顯示:
看起來好像還滿不錯的!!畫面都有正常顯示...等等!!這裡怎麼跑版了?:
別緊張,這是因為我們還沒有處理到這個區塊。這一個區塊裡有一個 UI 元件是跟甜點那頁會一起共用的,還記得嗎?
接下來我們就先來處理一下這一塊。
首先先打開素材 assets/css
裡的 choice-item.css
檔,這裡面都是跟甜點共用的那塊區塊的樣式設定。我們將它全部複製之後,貼到我們專案裡的 product-item.component.css
裡。
接著先幫我找到這個設定:
然後用以下的設定把它替換掉:
.choice-item .img-container {
height: 315px;
}
.choice-item .img-container img {
width: 100%;
height: 100%;
object-fit: cover;
}
這部分因為當初在切版的時候沒有發現 object-fit 這個設定,直到我在寫這篇文章的時候才發現,所以趕快請大家更改一下。
不過這個設定要很高的瀏覽器版本才有支援,所以要使用之前請特別留意。
接著再把 home.component.html
裡的這個區塊的程式碼複製貼到 product-item.component.html
裡:
貼完之後,幫我把下圖中的 HTML:
替換成:
<div class="img-container">
<img src="assets/images/others/heather-schwartz-493946-unsplash.jpg" alt="">
</div>
再來我們到 home.module.ts
裡 import
ProductItemModule ,這樣才能夠在 home.component.html
裡使用我們做好的 ProductItemComponent :
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HomeRoutingModule } from './home-routing.module';
import { HomeComponent } from './home.component';
import { ProductItemModule } from '../shared/product-item/product-item.module';
@NgModule({
imports: [
CommonModule,
HomeRoutingModule,
ProductItemModule
],
declarations: [HomeComponent]
})
export class HomeModule { }
最後則是到 home.component.html
裡把原本這一大串的程式碼:
替換成:
<section class="today-choice">
<app-product-item></app-product-item>
</section>
調整完之後來看一下畫面:
很好,看來是成功了!不過目前只有一個商品,我們先用奇怪的方式處理,後面再來處理資料的部份:
<app-product-item *ngFor="let item of [1, 2, 3]"></app-product-item>
然後再到 home.component.css
裡加上:
app-product-item {
display: inline-block;
}
app-product-item:nth-child(2) {
margin: 0px 20px;
}
加完之後再來看一下畫面:
Perfect!!
這樣我們首頁就完成基本的套版了,資料我們留到最後再來處理。
完成首頁的套版之後,有幾頁比較簡單的如登入頁、購物車頁以及結帳成功頁也可以先套起來,基本上這幾頁所對應的素材檔案以及專案檔案是:
pages/
裡的 login.html
assets/css/
裡的 login.css
login.component.html
login.component.css
pages/
裡的 cart.html
assets/css/
裡的 cart.css
cart.component.html
cart.component.css
pages/
裡的 checkout-success.html
assets/css/
裡的 checkout-success.css
success.component.html
success.component.css
試著自己套套看吧,記得只要中間那塊而已噢!!
有任何問題的話,應該上面都有提到過,再仔細檢查看看!
如果還是不知道問題在哪裡的話,歡迎在底下留言給我!
套完之後應該會像這樣:
那今天的套版就先到這裡囉,我們明天見!!
請問 分頁都會跑板ㄟ 這該怎麼處理
Hi, brad840628
這看起來有可能是 html 或者是 css 的問題,要麻煩你自行檢查看看噢!
請問 購物車結帳按鈕
我的設定如下
<p class="checkout font-dark-green"><a [routerLink]="appPath.checkout">結帳</a></p>
然後在點擊的時候出現undefined的錯誤
TypeError: Cannot read property 'checkout' of undefined
請問我大概是哪裡沒有設定好?
Hi kossokx,
就錯誤訊息看來,是因為 appPath
的值為 undefined
造成的,請問在 Component 裡有正確將 appPath
的值正確引入嗎?
請問在app-routing.module.ts 中引入外
需要在cart-routing.module.ts 或是 cart.module.ts 中引入嗎?
還是有點不太了解,路由設定跟上下引用的關係
Hi kossokx,
這裡的問題跟路由設定無關,是範例中的路徑定義檔沒有正確引入到 Component 的問題。
在 success.component.html
的 <a [routerLink]="[path.home]">繼續逛逛</a>
,可以正常轉回首頁
然而 cart.component.html
要轉到結帳頁卻使用 <a [routerLink]="['..', path.checkout]">
我使用 enableTracing
發現並沒有出現未定義的路徑而跳轉home
和 success
是位於同一層級的,為什麼可以不需要使用 <a [routerLink]="['..', path.home]">
?
Hi obelisk0114,
這是因為 path.home
的值是空字串的關係,所以該連結會直接回到首頁,其他的情況都會在當前路由往後加,如 /cart/checkout
。
也就是說空字串可以上升一級 ?
像是這樣嗎 ?
/a/b/c
使用 <a [routerLink]="['']"> 可以轉到
/a/b
不是上升一層,是直接回到 ''
的路由
HI 版主你好
由於當初你把一個馬卡龍複製成三份,這會被視為三個物件
所以你在home.component.css下了這個設定
才能順利的把馬卡龍切開
但是現在我把三個馬卡龍視為一個物件(一體)
home.component.html
我要怎麼設定才能讓商品圖片中間有空隙
另外我想問在product-item.component.html裡的class(有3個馬卡龍,2個class)
是否要在product-item.component.css裡額外寫一個一樣的class給choice-item desktop使用,還是可以直接把其餘的2個class改成choice-item然後直接套用?
可以稍微解釋一下為什麼另外兩個馬卡龍和第一個馬卡龍使用不一樣的class嗎?
Hi json1999,
既然你已經將三個馬卡龍合而為一,那 CSS 就該寫在 ProductItemComponent 對應的 CSS 檔裡,不適用於原本的 CSS設定。
如果不管有沒有 desktop
都會是一樣的 CSS 設定的話,那 desktop
這個 class 就沒有存在的必要了。
我不太懂你的意思,可能要麻煩你說清楚一些~ 而我看原本的原始碼裡,只有一個 ProductItemComponent
首先先謝謝版主的回應
關於你的第3個問題,因為我把3個馬卡龍都寫在ProductItemComponent
版主你只有寫1個,所以我想問3個馬卡龍是否要寫在同一個ProductItemComponent裡面?還是要分開寫成三個Component,然後各自產生html、css?最後在import到home.module.ts給home.component.html使用
可不可以說一下製作3個馬卡龍的流程,因為我還是有點不清楚
Hi json1999,
我會只有寫一個 ProductItemComponent 的原因是因為它是能夠被重複使用的。
你想想一般店家在上架商品時,是一次上三個商品,還是一個一個上?
每個商品在呈現上最大的不一樣的不外乎就是名稱
、敘述
、圖片
、數量
、尺寸
等資訊,而這些都可以透過 Component 的 Input
來傳遞資料進去,然後透過一個迴圈就能夠將商家的所有商品呈現出來。
例如:
<app-product-item
*ngFor="let item of productList"
[imgUrl]="item.imgUrl"
[title]="item.title"
[description]="item.description"
></app-product-item>
因此,你覺得只用一個 ProductItemComponent 的彈性較大,還是三個寫在一起的彈性較大?
感謝版主的回應
應該是寫成3個ProductItemComponent的彈性比較大
經過我調整成3個ProductItemComponent後又產生了一些問題
關於home.component.css裡的程式我有點不清楚
app-product-item:nth-child(2)是指home.component.html裡面的app-product-item這個標籤下的第2個物件,還是指產生的第2個app-product-item(下面這一個)?
我去看了css的nth-child方法,感覺是第一個
當我套用你原本的設定會變成3個馬卡龍順序亂掉
然後我把它全部變成一樣之後
就成功了
但是只有第二個馬卡龍有套用到屬性,請問這樣是對的嗎?
還是3個都要套用到?該怎麼下css語法?
Hi json1999,
我的原意是只需要一個 ProductItemComponent
即可,切成三個你要維護三份同樣的程式碼...
關於 CSS 的部份,你可以參考知名講師 Amos 的教學文章:使用CSS3 :nth-child(n) 選取器教學
你覺得只用一個 ProductItemComponent 的彈性較大,還是三個寫在一起的彈性較大?
請問一下我當初不是只有1個ProductItemComponent裡面寫3個馬卡龍?
你這句話是不是鬼打牆?(1個ProductItemComponent不等於3個寫在一起????)
可以直接告訴我shared這個資料夾下會有什麼東西嗎?
還有product-item.component.html裡到底要寫什麼嗎?
還有你當初寫的程式碼
<app-product-item *ngFor="let item of [1, 2, 3]">
這會產生3個app-product-item
導致你可以下這個CSS
app-product-item:nth-child(2) {
margin: 0px 20px;
}
因為它會去找第2個app-product-item,然後幫它加上CSS
但是我現在只有1個app-product-item
所以我就沒辦法用這行程式碼去改
我在home.component.css發現有這行程式,但它沒作用
.choice-item:nth-child(2) {
margin: 0px 20px;
}
我把它複製到product-item.component.css
結果中間那張圖就可以套到CSS
為什麼你在home.component.css寫這行程式它可以直接套上CSS
app-product-item:nth-child(2) {
margin: 0px 20px;
}
然而我用CLASS(最上面那行)卻不行加上CSS,CSS不是有權重關係?
對了首頁那3張馬卡龍只要把視窗縮小圖會疊再一起
Hi json1999,
先前可能是我語意不清或太過於婉轉所以讓你摸不著頭緒,我的錯,我就再說清楚一些。
*ngFor
一次將其顯示在畫面上即可。而如果按照你的作法, ProductItemComponent 裡面有三個馬卡龍(也就是三個商品),請問,你如何將10個商品呈現出來?
當然,其實也不難,就多寫點程式碼而已,只要你做出同樣的效果,我相信客戶都會買單。
沒有套用成功的原因有很多,如打錯字、權重、Shadow dom 等等,一切都看要看原始碼才會知道,但我不是通靈少女,而通靈少女也沒有他心通,資訊太少無法判斷真正的原因。
非常感謝告知小圖會疊在一起的問題。
版主是否可以額外寫一下如何利用一個ProductItemComponent就展現出3個馬卡龍?
我去看了Day 05的*ngfor,但那是一個app.component.html 對應一個app.component.ts
然而這個是home.component.html以及product-item.component.html對應product-item.component.ts
我不知道該怎麼去撰寫程式
home.component.html
product-item.component.html
product-item.component.ts
產生的圖形
我知道product-item.component.html會產生三個圖疊再一起
要把它(ngfor)加在home.component.html
但是home.component.html要行跨product-item.component.html我就不會下語法
Hi, json1999
原本在 home.component.html
裡的程式碼:
<section class="today-choice">
<app-product-item *ngFor="let item of [1, 2, 3]"></app-product-item>
</section>
這就是用一個 ProductItemComponent
產生出 3
個馬卡龍的方式,而如果你想要有5個馬卡龍,就把 [1, 2, 3]
改成 [1, 2, 3, 4, 5]
就可以;而這代表的意思是,你要有幾個馬卡龍,就給他多少長度的陣列資料,自然就會迴圈出來。
當然實際上不可能用 [1, 2, 3]
這樣子的資料,而是你可能會有個裝著所有馬卡龍的資料的屬性或變數 productList
,然後就可能像這樣:
<section class="today-choice">
<app-product-item *ngFor="let product of productList" [item]="product"></app-product-item>
</section>
至於黏著什麼的,不過就是在 CSS 上多加個 margin-bottom
如:
app-product-item {
display: inline-block;
margin-bottom: 10px;
}